package my.study.c.consul.provider.impl.app.util;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.IFill;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.querys.MySqlQuery;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import com.baomidou.mybatisplus.generator.config.rules.IColumnType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.fill.Column;
import com.baomidou.mybatisplus.generator.keywords.MySqlKeyWordsHandler;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;

// 演示例子，执行 main 方法控制台输入模块表名回车自动生成对应项目目录中
public class CodeGenerator {

    /**
     * <p>
     * 读取控制台内容
     * </p>
     */
    public static String scanner(String tip) {
        Scanner scanner = new Scanner(System.in);
        StringBuilder help = new StringBuilder();
        help.append("请输入" + tip + "：");
        System.out.println(help.toString());
        if (scanner.hasNext()) {
            String ipt = scanner.next();
            if (StringUtils.isNotBlank(ipt)) {
                return ipt;
            }
        }
        throw new MybatisPlusException("请输入正确的" + tip + "！");
    }

    public static void main(String[] args) {
        String dsUrl = "jdbc:mysql://127.0.0.1:3306/blog?useUnicode=true&useSSL=false&characterEncoding=utf8";
        String dsUsername = "root";
        String dsPassword = "root";
        DataSourceConfig.Builder dataSourceConfig = new DataSourceConfig.Builder(dsUrl, dsUsername, dsPassword)
                .dbQuery(new MySqlQuery())
                .typeConvert(new MySqlTypeConvert())
                .keyWordsHandler(new MySqlKeyWordsHandler());

        dataSourceConfig.typeConvert(new MySqlTypeConvert() {
            public IColumnType processTypeConvert(GlobalConfig globalConfig, String fieldType) {
                String t = fieldType.toLowerCase();
                if (t.contains("tinyint")) {
                    return DbColumnType.INTEGER;
                }
                if (t.contains("bit(1)")) {
                    return DbColumnType.INTEGER;
                }
                return super.processTypeConvert(globalConfig, fieldType);
            }
        });
//
//        FastAutoGenerator.create(dataSourceConfig)
//                .globalConfig((scanner, builder) -> {
//                    // 全局配置
//                    String projectPath = System.getProperty("user.dir");
//                    builder.outputDir(projectPath + "/c-consul-provider/src/main/java");
//                    builder.author("chnyang");
//                    builder.enableSwagger();
//                })
//                .packageConfig((scanner, builder) -> {
//                    // 包配置
//                    builder.moduleName(scanner.apply("请输入包名"));
//                    builder.parent("my.study.c.consul.provider.app");
//                })
//                .injectionConfig((scanner, builder) -> {
//                    // 自定义配置
//                    builder.beforeOutputFile();
//                })
//                .strategyConfig((scanner, builder) -> {
//                    // 策略配置
//                    builder.addTablePrefix("t_");
//                    builder.addInclude(getTables(scanner.apply("请输入表名，多个英文逗号分隔？所有输入 all")))
//                            .entityBuilder()
//                            .enableLombok()
//                            .addTableFills(new Column("create_time", FieldFill.INSERT))
//                            .build();
//                })
//                .templateEngine(new FreemarkerTemplateEngine())
//                .execute();

        // 全局配置
        GlobalConfig.Builder globalConfigBuilder = new GlobalConfig.Builder();
        // 代码生成目录
        String projectPath = System.getProperty("user.dir");
        globalConfigBuilder.outputDir(projectPath + "/c-consul-provider/src/main/java");

        // 作者
        globalConfigBuilder.author("chnyang");
        // 结束时是否打开文件夹
        globalConfigBuilder.disableOpenDir();
        // 是否覆盖旧的文件
        //globalConfigBuilder.fileOverride();
        // 实体属性Swagger2注解
        globalConfigBuilder.enableSwagger();

        // 包配置，如模块名、实体、mapper、service、controller等
        PackageConfig.Builder packageConfigBuilder = new PackageConfig.Builder();
        packageConfigBuilder.parent("my.study.c.consul.provider.app");
        packageConfigBuilder.moduleName(scanner("请输入包名"));
        packageConfigBuilder.parent("my.study.c.consul.provider.app");
        packageConfigBuilder.entity("entity");
        packageConfigBuilder.mapper("mapper");
        packageConfigBuilder.service("service");
        //packageConfigBuilder.serviceImpl("");
        packageConfigBuilder.controller("controller");

        // ------------------------------ 策略配置 Start
        StrategyConfig.Builder strategyConfigBuilder = new StrategyConfig.Builder();
        // 设置需要映射的表名
        strategyConfigBuilder.addInclude(
                getTables(scanner("请输入表名，多个英文逗号分隔, 所有输入 all"))
        );
        // 去除前缀"t_"
        strategyConfigBuilder.addTablePrefix("t_");
        // -------------------- Entity 策略配置
        // 主键生成策略
        // strategyConfigBuilder.entityBuilder().idType(IdType.INPUT);
        // 下划线转驼峰
        strategyConfigBuilder.entityBuilder().naming(NamingStrategy.underline_to_camel);
        strategyConfigBuilder.entityBuilder().columnNaming(NamingStrategy.underline_to_camel);
        // 开启链式模型
        strategyConfigBuilder.entityBuilder().enableChainModel();
        // 开启Lombok模型
        strategyConfigBuilder.entityBuilder().enableLombok();
        // Boolean 类型字段移除 is 前缀
        // strategyConfigBuilder.entityBuilder().enableRemoveIsPrefix();
        // 开启生成实体时生成字段注解
        strategyConfigBuilder.entityBuilder().enableTableFieldAnnotation();
        // 逻辑删除
        strategyConfigBuilder.entityBuilder().logicDeleteColumnName("deleted_at");
        strategyConfigBuilder.entityBuilder().logicDeletePropertyName("deletedAt");
        // 乐观锁
//        strategyConfigBuilder.entityBuilder().versionColumnName("version");
//        strategyConfigBuilder.entityBuilder().versionPropertyName("version");
        // 自动填充
        IFill createTime = new Column("createdAt", FieldFill.INSERT);
        IFill updateTime = new Column("updatedAt", FieldFill.INSERT_UPDATE);
        strategyConfigBuilder.entityBuilder().addTableFills(createTime, updateTime);
        // -------------------- Controller 策略配置
        // 设置父类
        // strategyConfigBuilder.controllerBuilder().superClass(Class<BaseController.class>);
        // strategyConfigBuilder.controllerBuilder().superClass("com.baomidou.global.BaseController");
        // 开启生成@RestController 控制器
        strategyConfigBuilder.controllerBuilder().enableRestStyle();
        // 开启驼峰转连字符
        strategyConfigBuilder.controllerBuilder().enableHyphenStyle();
        // -------------------- Service 策略配置
        // 设置 IService 父类
        strategyConfigBuilder.serviceBuilder().superServiceClass(IService.class);
        // strategyConfigBuilder.serviceBuilder().superServiceClass("com.baomidou.global.BaseService");
        // 设置 ServiceImpl 父类
        strategyConfigBuilder.serviceBuilder().superServiceImplClass(ServiceImpl.class);
        // strategyConfigBuilder.serviceBuilder().superServiceImplClass("com.baomidou.global.BaseService");
        // -------------------- Mapper 策略配置
        // 设置父类
        strategyConfigBuilder.mapperBuilder().superClass(BaseMapper.class);
        // strategyConfigBuilder.mapperBuilder().superClass("com.baomidou.global.BaseMapper");
        // 开启 @Mapper 注解
        strategyConfigBuilder.mapperBuilder().enableMapperAnnotation();
        // 启用 BaseResultMap 生成
        strategyConfigBuilder.mapperBuilder().enableBaseResultMap();
        // 启用 BaseColumnList
        strategyConfigBuilder.mapperBuilder().enableBaseColumnList();
        // 设置缓存实现类
        // strategyConfigBuilder.mapperBuilder().cache(MyMapperCache.class);
        // ------------------------------ 策略配置 End

        // 自定义配置
        //InjectionConfig.Builder injectionConfigBuilder = new InjectionConfig.Builder();

        // 模板引擎配置
        //TemplateConfig.Builder templateConfigBuilder = new TemplateConfig.Builder();
        // 如果模板引擎是 freemarker
        //String templatePath = "/templates/mapper.xml.ftl";
        // 如果模板引擎是 velocity
        //String templatePath = "/templates/mapper.xml.vm";
        //templateConfigBuilder.entity()

        // 创建代码生成器对象，加载配置
        AutoGenerator autoGenerator = new AutoGenerator(dataSourceConfig.build());
        autoGenerator.global(globalConfigBuilder.build());
        autoGenerator.packageInfo(packageConfigBuilder.build());
        autoGenerator.strategy(strategyConfigBuilder.build());
        //autoGenerator.injection(injectionConfigBuilder.build());
        //autoGenerator.template();

        // 执行
        autoGenerator.execute();
    }



    protected static List<String> getTables(String tables) {
        return "all".equals(tables) ? Collections.emptyList() : Arrays.asList(tables.split(","));
    }

}
